/**
 * 单例模式重构示例
 * 
 * 展示如何将现有单例代码重构为统一的单例模式
 * 
 * @author AI Assistant
 * @date 2025-11-27
 */

import { LazySingleton, AsyncSingleton, SingletonManager } from './Singleton';
import { Log } from '../logger/LoggerGlobal';

// ============================================================================
// 示例 1: 重构简单单例
// ============================================================================

/**
 * ❌ 重构前：传统单例写法
 */
class OldConfigManager {
    private static instance: OldConfigManager | null = null;
    private config: Record<string, any> = {};
    
    private constructor() {
        this.loadConfig();
    }
    
    static getInstance(): OldConfigManager {
        if (!OldConfigManager.instance) {
            OldConfigManager.instance = new OldConfigManager();
        }
        return OldConfigManager.instance;
    }
    
    private loadConfig(): void {
        // 加载配置
    }
    
    getConfig(key: string): any {
        return this.config[key];
    }
}

/**
 * ✅ 重构后：使用 LazySingleton 基类
 */
export class ConfigManager extends LazySingleton<ConfigManager> {
    private config: Record<string, any> = {};
    
    protected constructor() {
        super();
        this.loadConfig();
        
        // 注册到单例管理器
        SingletonManager.register('ConfigManager', this);
    }
    
    private loadConfig(): void {
        Log.general.debug('加载配置');
        // 加载配置
    }
    
    getConfig(key: string): any {
        return this.config[key];
    }
    
    override destroy(): void {
        Log.general.debug('销毁 ConfigManager');
        this.config = {};
        SingletonManager.unregister('ConfigManager');
    }
}

// 使用
// const configManager = ConfigManager.getInstance();

// ============================================================================
// 示例 2: 重构异步单例
// ============================================================================

/**
 * ❌ 重构前：手动管理异步初始化
 */
class OldAssetLoader {
    private static instance: OldAssetLoader | null = null;
    private static initPromise: Promise<OldAssetLoader> | null = null;
    private assets: Map<string, any> = new Map();
    
    private constructor() {}
    
    static async getInstance(): Promise<OldAssetLoader> {
        if (!OldAssetLoader.initPromise) {
            OldAssetLoader.initPromise = (async () => {
                const instance = new OldAssetLoader();
                await instance.init();
                OldAssetLoader.instance = instance;
                return instance;
            })();
        }
        return OldAssetLoader.initPromise;
    }
    
    private async init(): Promise<void> {
        // 异步初始化
        await this.loadAssets();
    }
    
    private async loadAssets(): Promise<void> {
        // 加载资源
    }
}

/**
 * ✅ 重构后：使用 AsyncSingleton 基类
 */
export class AssetLoader extends AsyncSingleton<AssetLoader> {
    private assets: Map<string, any> = new Map();
    
    protected constructor() {
        super();
        SingletonManager.register('AssetLoader', this);
    }
    
    protected async init(): Promise<void> {
        Log.general.debug('异步初始化 AssetLoader');
        await this.loadAssets();
    }
    
    private async loadAssets(): Promise<void> {
        // 模拟异步加载
        await new Promise(resolve => setTimeout(resolve, 100));
        Log.general.debug('资源加载完成');
    }
    
    getAsset(key: string): any {
        return this.assets.get(key);
    }
    
    override async destroy(): Promise<void> {
        Log.general.debug('销毁 AssetLoader');
        this.assets.clear();
        SingletonManager.unregister('AssetLoader');
    }
}

// 使用
// const assetLoader = await AssetLoader.getInstance();

// ============================================================================
// 示例 3: 重构直接导出的单例
// ============================================================================

/**
 * ❌ 重构前：直接导出实例
 */
class OldLoggerManager {
    private logs: string[] = [];
    
    constructor() {
        this.init();
    }
    
    private init(): void {
        // 初始化
    }
    
    log(message: string): void {
        this.logs.push(message);
    }
}

// 直接导出实例
// export const oldLoggerManager = new OldLoggerManager();

/**
 * ✅ 重构后：使用 LazySingleton + 延迟导出
 */
export class LoggerManager extends LazySingleton<LoggerManager> {
    private logs: string[] = [];
    
    protected constructor() {
        super();
        this.init();
        SingletonManager.register('LoggerManager', this);
    }
    
    private init(): void {
        Log.general.debug('初始化 LoggerManager');
    }
    
    log(message: string): void {
        this.logs.push(message);
    }
    
    getLogs(): string[] {
        return [...this.logs];
    }
    
    override destroy(): void {
        Log.general.debug('销毁 LoggerManager');
        this.logs = [];
        SingletonManager.unregister('LoggerManager');
    }
}

// 导出便捷访问器
export const loggerManager = LoggerManager.getInstance();

// ============================================================================
// 示例 4: 重构带泛型的单例
// ============================================================================

/**
 * ❌ 重构前：带泛型的单例
 */
class OldCacheManager<T> {
    private static instances: Map<string, OldCacheManager<any>> = new Map();
    private cache: Map<string, T> = new Map();
    
    private constructor(private readonly namespace: string) {}
    
    static getInstance<T>(namespace: string): OldCacheManager<T> {
        if (!OldCacheManager.instances.has(namespace)) {
            OldCacheManager.instances.set(
                namespace,
                new OldCacheManager<T>(namespace)
            );
        }
        return OldCacheManager.instances.get(namespace)!;
    }
    
    set(key: string, value: T): void {
        this.cache.set(key, value);
    }
    
    get(key: string): T | undefined {
        return this.cache.get(key);
    }
}

/**
 * ✅ 重构后：使用命名空间单例工厂
 */
export class CacheManager<T> {
    private static instances: Map<string, CacheManager<any>> = new Map();
    private cache: Map<string, T> = new Map();
    
    private constructor(private readonly namespace: string) {
        Log.general.debug('创建缓存管理器', { namespace });
        SingletonManager.register(`CacheManager:${namespace}`, this);
    }
    
    static getInstance<T>(namespace: string): CacheManager<T> {
        if (!CacheManager.instances.has(namespace)) {
            CacheManager.instances.set(
                namespace,
                new CacheManager<T>(namespace)
            );
        }
        return CacheManager.instances.get(namespace)!;
    }
    
    static resetInstance(namespace: string): void {
        const instance = CacheManager.instances.get(namespace);
        if (instance) {
            instance.destroy();
            CacheManager.instances.delete(namespace);
        }
    }
    
    set(key: string, value: T): void {
        this.cache.set(key, value);
    }
    
    get(key: string): T | undefined {
        return this.cache.get(key);
    }
    
    clear(): void {
        this.cache.clear();
    }
    
    destroy(): void {
        Log.general.debug('销毁缓存管理器', { namespace: this.namespace });
        this.cache.clear();
        SingletonManager.unregister(`CacheManager:${this.namespace}`);
    }
}

// 使用
// const userCache = CacheManager.getInstance<User>('user');
// const configCache = CacheManager.getInstance<Config>('config');

// ============================================================================
// 示例 5: 重构需要参数的单例
// ============================================================================

/**
 * ✅ 使用工厂模式 + 单例
 */
export class DatabaseConnection extends LazySingleton<DatabaseConnection> {
    private connectionString: string = '';
    private connected: boolean = false;
    
    protected constructor() {
        super();
        SingletonManager.register('DatabaseConnection', this);
    }
    
    /**
     * 配置连接（首次调用时）
     */
    configure(connectionString: string): void {
        if (this.connected) {
            Log.general.warn('数据库已连接，无法重新配置');
            return;
        }
        
        this.connectionString = connectionString;
        Log.general.debug('配置数据库连接', { connectionString });
    }
    
    /**
     * 连接数据库
     */
    async connect(): Promise<void> {
        if (this.connected) {
            Log.general.debug('数据库已连接');
            return;
        }
        
        if (!this.connectionString) {
            throw new Error('未配置数据库连接字符串');
        }
        
        // 模拟异步连接
        await new Promise(resolve => setTimeout(resolve, 100));
        this.connected = true;
        Log.general.info('数据库连接成功');
    }
    
    /**
     * 断开连接
     */
    async disconnect(): Promise<void> {
        if (!this.connected) {
            return;
        }
        
        // 模拟异步断开
        await new Promise(resolve => setTimeout(resolve, 50));
        this.connected = false;
        Log.general.info('数据库断开连接');
    }
    
    override destroy(): void {
        if (this.connected) {
            Log.general.warn('销毁前未断开数据库连接');
        }
        SingletonManager.unregister('DatabaseConnection');
    }
}

// 使用
// const db = DatabaseConnection.getInstance();
// db.configure('mongodb://localhost:27017');
// await db.connect();

// ============================================================================
// 使用示例总结
// ============================================================================

/**
 * 运行所有示例
 */
export async function runSingletonExamples() {
    Log.styled('━'.repeat(60), 'separator');
    Log.styled('🔧 单例模式重构示例', 'title');
    Log.styled('━'.repeat(60), 'separator');
    
    // 1. 简单单例
    Log.styled('📚 示例 1: 简单单例', 'large');
    const configManager = ConfigManager.getInstance();
    Log.general.info('ConfigManager 实例已创建');
    
    // 2. 异步单例
    Log.styled('📚 示例 2: 异步单例', 'large');
    const assetLoader = await AssetLoader.getInstance();
    Log.general.info('AssetLoader 实例已创建');
    
    // 3. 直接导出单例
    Log.styled('📚 示例 3: 导出单例', 'large');
    loggerManager.log('测试日志');
    Log.general.info('LoggerManager 使用完成', {
        logCount: loggerManager.getLogs().length
    });
    
    // 4. 泛型单例
    Log.styled('📚 示例 4: 泛型单例', 'large');
    const userCache = CacheManager.getInstance<{ id: number; name: string }>('user');
    userCache.set('user1', { id: 1, name: 'Alice' });
    Log.general.info('CacheManager 使用完成');
    
    // 5. 带配置的单例
    Log.styled('📚 示例 5: 带配置的单例', 'large');
    const db = DatabaseConnection.getInstance();
    db.configure('mongodb://localhost:27017');
    await db.connect();
    Log.general.info('DatabaseConnection 连接成功');
    
    // 打印单例管理器统计
    SingletonManager.printStatistics();
    
    Log.styled('━'.repeat(60), 'separator');
    Log.styled('✅ 所有示例运行完成', 'success');
    Log.styled('━'.repeat(60), 'separator');
}

/**
 * 测试单例重置
 */
export async function testSingletonReset() {
    Log.styled('━'.repeat(60), 'separator');
    Log.styled('🧪 测试单例重置', 'title');
    Log.styled('━'.repeat(60), 'separator');
    
    // 创建实例
    const manager1 = ConfigManager.getInstance();
    Log.general.info('第一次获取实例', { instanceId: (manager1 as any).constructor.name });
    
    // 重置实例
    ConfigManager.resetInstance();
    Log.general.info('重置实例完成');
    
    // 重新创建
    const manager2 = ConfigManager.getInstance();
    Log.general.info('第二次获取实例', { instanceId: (manager2 as any).constructor.name });
    
    // 验证是否为新实例
    const isSameInstance = manager1 === manager2;
    Log.general.info('实例比较', { isSameInstance });
    
    Log.styled('━'.repeat(60), 'separator');
}

